﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using com.skype.api;
using com.skype.ipc;

/**Session Object. Encapsulates common aspects of the SkypeKit.*/
namespace Hugo
{
    class MySession
    {
        public String myAccountName; //Name of the target Skype account, which is actually the Skype Name of the user that created it.
        public SignInMgr mySignInMgr = new SignInMgr();
        public Skype mySkype = null; //Skype instance 
        public ClientConfiguration myClientConfiguration = null; //SkypeKit configuration instance. Contains transport port/IP address and certificate file data.
        public Account myAccount = null; //Account instance. Set on successful login, not during session creation!
        public Boolean callActive = false; // Whether we are currently in a call. Set to true when a Conversation goes live 
        public Account.Status loginStatus = Account.Status.LOGGED_OUT; //Cached status of this session's associated Account.

        public Listeners myListeners = null; // Callbacks/event handlers
        public static String IP_ADDR = "127.0.0.1"; //Server IP Address.
        public static int PORT_NUM = 8963; // Server Port.

        // Creates most everything needed for a session; the Account instance is populated during sign-in. 
        public Boolean doCreateSession(String accountName, String pathName)
        {
            if ((accountName != null) && (accountName.Length != 0))
            {
                myAccountName = accountName; 
            }
            else
            {
                Console.Write("Cannot initialize session instance - no account name!");
            }

            // Set up our session with the SkypeKit runtime...
            mySkype = new Skype();
            myClientConfiguration = new ClientConfiguration();
            myClientConfiguration.setTcpTransport(IP_ADDR, PORT_NUM);
            myClientConfiguration.setCertificate(pathName);

            myListeners = new Listeners(this);

            Console.WriteLine("Instantiated Skype, ClientConfiguration, and Listeners instances...");
            mySkype.init(myClientConfiguration, myListeners);
            mySkype.start(); // You must invoke start --immediately-- after invoking init!

            // Get the Account
            if ((myAccount = mySkype.getAccount(myAccountName)) == null)
            {
                return (false);
            }

            Console.WriteLine("Got Account for " + myAccountName);
            return (true);
        }

        // Tears down a tutorial session.
        public void doTearDownSession()
        {

            if (myListeners != null)
            {
                myListeners.unRegisterAllListeners();
                myListeners = null;
            }
            // Closing Skype also disconnects the transport
            if (mySkype != null)
            {
                mySkype.stop();
                mySkype = null;
            }
        }

        //Retrieves the current login status of this session's Account.
        public Account.Status getLoginStatus()
        {

            return (this.loginStatus);
        }

        //Establishes the login status of this session's Account.
        public void setLoginStatus(Account.Status loginStatus)
        {

            this.loginStatus = loginStatus;

            return;
        }

        //Determines if an Account is signed in.
        public Boolean isLoggedIn()
        {

            if (this.loginStatus == Account.Status.LOGGED_IN)
            {
                return (true);
            }
            return (false);
        }

        //Assigns active input and output devices from among those available.
        public Boolean setupAudioDevices(int micIdx, int spkrIdx)
        {
            Boolean passFail = true;	// Ever the optimist, assume success!

            Skype.GetAvailableRecordingDevicesResponse inputDevices = mySkype.getAvailableRecordingDevices();
            Skype.GetAvailableOutputDevicesResponse outputDevices = mySkype.getAvailableOutputDevices();

            if (micIdx > (inputDevices.handleList.Length + 1))
            {
                passFail = false;
            }

            if (spkrIdx > (outputDevices.handleList.Length + 1))
            {
                passFail = false;
            }

            if (passFail)
            {
                mySkype.selectSoundDevices(inputDevices.handleList[micIdx],
                        outputDevices.handleList[spkrIdx], outputDevices.handleList[spkrIdx]);
                mySkype.setSpeakerVolume(100);
            }

            return (passFail);
        }

    }
}